package com.jlkj.web.shopnew.service.impl;

import cc.s2m.web.utils.webUtils.service.BaseServiceImpl;
import com.google.common.collect.Lists;
import com.jlkj.web.shopnew.constant.Constant;
import com.jlkj.web.shopnew.constant.ConstantDateType;
import com.jlkj.web.shopnew.core.StatusCode;
import com.jlkj.web.shopnew.dao.StaffMapper;
import com.jlkj.web.shopnew.dto.DateDto;
import com.jlkj.web.shopnew.exception.BussinessException;
import com.jlkj.web.shopnew.pojo.Company;
import com.jlkj.web.shopnew.pojo.CompanyInvite;
import com.jlkj.web.shopnew.pojo.Staff;
import com.jlkj.web.shopnew.pojo.mongo.FollowMongo;
import com.jlkj.web.shopnew.pojo.mongo.LogMongo;
import com.jlkj.web.shopnew.request.*;
import com.jlkj.web.shopnew.service.*;
import com.jlkj.web.shopnew.service.mongo.ICustomerMongo;
import com.jlkj.web.shopnew.service.mongo.IFollowMongo;
import com.jlkj.web.shopnew.service.mongo.ILogMongo;
import com.jlkj.web.shopnew.util.DateUtil;
import com.mongodb.client.result.UpdateResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class StaffImpl extends BaseServiceImpl<Staff, StaffMapper, Integer> implements IStaff {
    @Autowired
    private StaffMapper staffMapper;

    @Autowired
    private ICustomerMongo customerMongoService;

    @Autowired
    private ICompany companyService;

    @Autowired
    private ILogMongo logMongoService;

    @Autowired
    private IOrders ordersService;

    @Autowired
    private IFollowMongo followMongoService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ICompanyInvite companyInviteService;


    @Autowired
    private IConversionRate conversionRateService;

    protected StaffMapper getDao() {
        return staffMapper;
    }

    @Override
    public List<Integer> getCompanyStaff(int uid) {
        int companyId = companyService.getCompanyId(uid);

        if (companyId == -1) {
            throw new BussinessException(StatusCode.ERROR_NO_COMPANY);
        }

        Staff condiAll = new Staff();
        condiAll.setCompanyId(companyId);
        List<Staff> staffList = this.getList(condiAll);


        if (staffList == null || staffList.size() == 0) {
            return Lists.newArrayList(uid);
        }

        List<Integer> list = Lists.newArrayList();
        for (Staff staff : staffList) {
            list.add(staff.getStaffId());
        }

        return list;
    }


    @Override
    public List<Integer> getStaffUids(int uid) {
        int companyId = companyService.getCompanyId(uid);

        if (companyId == -1) {
            return Lists.newArrayList(uid);
        }

        Staff condiAll = new Staff();
        condiAll.setCompanyId(companyId);
        List<Staff> staffList = this.getList(condiAll);

        if (staffList == null || staffList.size() == 0) {
            return Lists.newArrayList(uid);
        }

        List<Integer> list = Lists.newArrayList();
        for (Staff staff : staffList) {
            list.add(staff.getStaffId());
        }

        return list;
    }

    @Override
    public List<StaffDto> staffSort(GetStaffSortRequest getStaffSortRequest) {
        DateDto dateDto = DateUtil.getDayByType(getStaffSortRequest.getDateType(),
                getStaffSortRequest.getStartDay(), getStaffSortRequest.getEndDay());

        Company bean = companyId(getStaffSortRequest.getUid());

        if (bean == null) {
            throw new BussinessException(StatusCode.ERROR_NO_COMPANY);
        }

        Staff condi = new Staff();
        condi.setCompanyId(bean.getId());
        List<Staff> staffList = getList(condi);
        List<StaffDto> list = new ArrayList<>();
        for (Staff staff : staffList) {
            int countType = getStaffSortRequest.getCountType();
            int count = 0;
            if (countType == 0) {
                //按照客户数
                count = conversionRateService.getCustomerByType(getStaffSortRequest,
                        dateDto, "customerTime");
            } else if (countType == 1) {
                //按照跟进数
                count = followMongoService.getFollowCount(getStaffSortRequest.getUid(), dateDto);
            } else if (countType == 2) {
                //按照订单数
                count = ordersService.getOrdersCount(getStaffSortRequest.getUid(), dateDto);
            } else {
                //按照转化率
                int intentionalCount = conversionRateService.getCustomerByType(getStaffSortRequest,
                        dateDto, "intentionalTime");
                int customerCount = conversionRateService.getCustomerByType(getStaffSortRequest,
                        dateDto, "customerTime");

                count = intentionalCount == 0 ? 0 :
                        new BigDecimal(customerCount)
                                .divide(new BigDecimal(intentionalCount))
                                .setScale(2, RoundingMode.HALF_UP).intValue();


            }

            StaffDto dto = new StaffDto();
            dto.setStaffId(staff.getStaffId());
            dto.setStaffName(staff.getStaffName());
            dto.setStaffPic(staff.getStaffPic());
            dto.setStaffPosition(staff.getStaffPosition());
            dto.setCount(count);
            list.add(dto);
        }

        Collections.sort(list, new Comparator<StaffDto>() {
            public int compare(StaffDto o1, StaffDto o2) {
                return o2.getCount() - o1.getCount();
            }
        });
        return list;
    }


    //1 客户总数：员工的客户总数/企业总客户数*100
    //2 跟进客户：员工的跟进客户数/企业总跟进客户数*100
    //3 昨日新增客户：员工的昨日新增客户数/企业昨日的跟进客户数*100
    //4 客户咨询数：员工昨日的咨询数/企业昨日总的咨询数*100
    //5 客户转化率：员工的客户转化率*100
    //6 成交订单：员工的成交订单/企业的成交订单*100
    @Override
    public List<StaffAnalysisDto> staffAnalysis(GetStaffAnalysisRequest getStaffAnalysisRequest) {
        Company bean = companyId(getStaffAnalysisRequest.getUid());
        if (bean == null) {
            throw new BussinessException(StatusCode.ERROR_NO_COMPANY);
        }


        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Staff condi = new Staff();
        condi.setCompanyId(bean.getId());
        List<Staff> staffList = getList(condi);
        List<Integer> listStaffIds = Lists.newArrayList();
        for (Staff staff : staffList) {
            listStaffIds.add(staff.getStaffId());
        }
        //统计总的
        //1 客户总数：员工的客户总数/企业总客户数*100
        //2 跟进客户：员工的跟进客户数/企业总跟进客户数*100
        //3 昨日新增客户：员工的昨日新增客户数/企业昨日的跟进客户数*100
        //4 客户咨询数：员工昨日的咨询数/企业昨日总的咨询数*100
        //5 客户转化率：员工的客户转化率*100
        //6 成交订单：员工的成交订单/企业的成交订单*100
        StatiscRequest statiscRequest = new StatiscRequest();
        statiscRequest.setBoss(true);
        statiscRequest.setUid(getStaffAnalysisRequest.getUid());
        statiscRequest.setDateType(ConstantDateType.ALL_DAY);
        DateDto dateDto = new DateDto();
        Date date = DateUtil.getMongoDate();
        dateDto.setEndDay(DateUtil.dateToISODate(format.format(date)));

        int customerAllCount = getCustomerAllCount(statiscRequest, dateDto);
        int followAllCount = this.getUserTypeFollowCount(statiscRequest, dateDto);
        int ordersAllCount = ordersService.getOrdersCount(statiscRequest, dateDto);

        statiscRequest.setDateType(ConstantDateType.YESTERDAY);
        dateDto = DateUtil.getDayByType(ConstantDateType.YESTERDAY, date, date);
        int yesterdayCustomerAddAllCount = this.getCustomerAllCount(statiscRequest, dateDto);
        int yseterdayCustomerChatAllCount = logMongoService.getChatCount(statiscRequest, dateDto);

        List<StaffAnalysisDto> list = new ArrayList<>();
        for (Staff staff : staffList) {
            StatiscRequest statiscRequestStaff = new StatiscRequest();
            statiscRequestStaff.setBoss(false);
            statiscRequestStaff.setUid(staff.getStaffId());
            statiscRequestStaff.setDateType(ConstantDateType.ALL_DAY);
            DateDto dateDtoStaff = new DateDto();
            dateDtoStaff.setEndDay(date);

            int customerStaffCount = getCustomerStaffCount(statiscRequestStaff, dateDtoStaff);
            int followStaffCount = this.getUserTypeFollowCount(statiscRequestStaff, dateDtoStaff);

            int ordersStaffCount = ordersService.getOrdersCount(statiscRequestStaff, dateDtoStaff);

            statiscRequest.setDateType(ConstantDateType.YESTERDAY);
            dateDtoStaff = DateUtil.getDayByType(ConstantDateType.YESTERDAY, date, date);
            int yesterdayCustomerAddStaffCount = this.getCustomerAllCount(statiscRequestStaff, dateDtoStaff);
            int yseterdayCustomerChatStaffCount = logMongoService.getChatCount(statiscRequestStaff,
                    dateDtoStaff);

            StaffAnalysisDto dto = new StaffAnalysisDto();

            BigDecimal customerScale = customerAllCount == 0 ? BigDecimal.ZERO :
                    new BigDecimal(customerStaffCount).divide(
                            new BigDecimal(customerAllCount)).setScale(2, RoundingMode.HALF_UP);
            dto.setCustomerScale(customerScale);

            BigDecimal followScale = followAllCount == 0 ? BigDecimal.ZERO :
                    new BigDecimal(followStaffCount).divide(
                            new BigDecimal(followStaffCount)).setScale(2, RoundingMode.HALF_UP);
            dto.setFollowScale(followScale);

            BigDecimal chatScale = yseterdayCustomerChatAllCount == 0 ? BigDecimal.ZERO :
                    new BigDecimal(yseterdayCustomerChatStaffCount).divide(
                            new BigDecimal(yseterdayCustomerChatAllCount)
                                    .setScale(2, RoundingMode.HALF_UP));
            dto.setChatScale(chatScale);

            BigDecimal customerAddScale = yesterdayCustomerAddAllCount == 0 ? BigDecimal.ZERO :
                    new BigDecimal(yesterdayCustomerAddStaffCount).divide(
                            new BigDecimal(yesterdayCustomerAddAllCount)
                                    .setScale(2, RoundingMode.HALF_UP));
            dto.setCustomerAddScale(customerAddScale);

            BigDecimal ordersScale = ordersAllCount == 0 ? BigDecimal.ZERO :
                    new BigDecimal(ordersStaffCount).divide(
                            new BigDecimal(ordersAllCount)
                    ).setScale(2, RoundingMode.HALF_UP);
            dto.setOrdersScale(ordersScale);

            BigDecimal allScale = customerScale.add(followScale)
                    .add(chatScale).add(customerAddScale).add(ordersScale);
            dto.setAllScale(allScale);

            //转换率
            GetConversionRateRequest rateRequest = new GetConversionRateRequest();
            rateRequest.setBoss(false);
            rateRequest.setUid(staff.getStaffId());
            rateRequest.setDateType(ConstantDateType.ALL_DAY);
            int intentional = conversionRateService.getAllOfCustomer(rateRequest, "intentionalTime");
            int customer = conversionRateService.getAllOfCustomer(rateRequest, "customerTime");

            BigDecimal rateScale = intentional == 0 ? BigDecimal.ZERO :
                    new BigDecimal(customer).divide(new BigDecimal(intentional))
                            .setScale(2, RoundingMode.HALF_UP);
            dto.setRateScale(rateScale);

            dto.setStaffId(staff.getStaffId());
            dto.setStaffName(staff.getStaffName());
            dto.setStaffPic(staff.getStaffPic());
            dto.setStaffPosition(staff.getStaffPosition());
            list.add(dto);
        }

        Collections.sort(list, new Comparator<StaffAnalysisDto>() {
            public int compare(StaffAnalysisDto o1, StaffAnalysisDto o2) {
                System.out.println(o2.getAllScale());
                System.out.println(o1.getAllScale());
                return o2.getAllScale().compareTo(o1.getAllScale());
            }
        });

        return list;
    }

    @Override
    public boolean deleteStaff(DeleteStaffRequest deleteStaffRequest) {
        Criteria criteria = new Criteria().andOperator(
                Criteria.where("belongUid").is(deleteStaffRequest.getUid())
        );

        Query query = Query.query(criteria);
        FollowMongo bean = this.mongoTemplate.findOne(query, FollowMongo.class);

        if (bean != null) {
            Update update = Update.update("belongUid", deleteStaffRequest.getBossId());
            UpdateResult result = this.mongoTemplate.updateMulti(query, update, FollowMongo.class);
        }

        //删除staff
        Staff staff = new Staff();
        staff.setStaffId(deleteStaffRequest.getUid());
        this.delete(staff);

        CompanyInvite condi = new CompanyInvite();
        condi.setUid(deleteStaffRequest.getUid());
        CompanyInvite udpate = new CompanyInvite();
        udpate.setFlag(2);

        companyInviteService.updateByCondition(udpate, condi);

        //足迹全部归老板
        try {
            Criteria criteria1 = new Criteria().andOperator(
                    Criteria.where("belongUid").is(deleteStaffRequest.getUid())
            );

            Query query1 = Query.query(criteria1);
            List<LogMongo> logMongo = this.mongoTemplate.find(query1, LogMongo.class);
            if (logMongo != null && logMongo.size() > 0) {
                Update update = Update.update("operationId", deleteStaffRequest.getBossId());
                UpdateResult result = this.mongoTemplate.updateMulti(query1, update, LogMongo.class);
            }
        }catch (Exception e){
            e.printStackTrace();
        }


        return true;
    }

    public Company companyId(int bossId) {
        Company condi = new Company();
        condi.setBossId(bossId);
        return companyService.getByCondition(condi);
    }

    private int getCustomerAllCount(StatiscRequest statiscRequest, DateDto dateDto) {
        int customerAllCount = logMongoService.
                getUserTypeCount(statiscRequest, dateDto, "customerTime");
        return customerAllCount;
    }

    private int getCustomerStaffCount(StatiscRequest statiscRequest, DateDto dateDto) {
        int customerAllCount = logMongoService.
                getUserTypeCount(statiscRequest, dateDto, "customerTime");
        return customerAllCount;
    }


    public int getUserTypeFollowCount(StatiscRequest statiscRequest, DateDto dateDto) {
        Criteria criteria = new Criteria().andOperator(
                Criteria.where("userType").in(Lists.newArrayList(2))
        );
        if (ConstantDateType.ALL_DAY.equals(statiscRequest.getDateType())) {
            criteria.and("updateTime").lte(dateDto.getEndDay());
        } else {
            criteria.andOperator(
                    Criteria.where("updateTime").lte(dateDto.getEndDay()),
                    Criteria.where("updateTime").gte(dateDto.getStartDay())
            );
        }

        if (statiscRequest.isBoss()) {
            List<Integer> list = this.getCompanyStaff(statiscRequest.getUid());
            criteria.and("belongUid").in(list);
        } else {
            criteria.and("belongUid").is(statiscRequest.getUid());
        }

        Aggregation agg = Aggregation.newAggregation(
                // 第一步：sql where 语句筛选符合条件的记录
                Aggregation.match(criteria),
                // 第二步：分组条件，设置分组字段
                Aggregation.group("userType").count().as("num"),
                Aggregation.project("num").andExclude("_id")
        );
        AggregationResults<Integer> results = mongoTemplate.aggregate(agg, Constant.FOLLOWMONGO, Integer.class);
        List<Integer> mappedResults = results.getMappedResults();
        return (mappedResults == null || mappedResults.size() == 0) ? 0 : mappedResults.get(0);
    }

}